package com.zhanghe.wzq;

import com.zhanghe.protocol.serializer.SerializerAlgorithm;
import com.zhanghe.protocol.serializer.SerializerManager;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

/**
 * Game
 *
 * @author Clevo
 * @date 2018/12/26
 */
@Data
public class Game {

    /**
     * 黑方
     */
    public String black;

    /**
     * 白方
     */
    public String white;

    /**
     * 棋子数组
     */
    public long[][] chess;

    /**
     * 每一步记录
     */
    public List<ChessStep> steps;

    public boolean over;
    /**
     * 下一步由谁下
     */
    public long nextStepUser;

    public int size;

    public Game(String black, String white,int size) {
        this.black = black;
        this.white = white;
        this.over = false;
        this.size = size;
        chess = new long[size][size];
        steps = new ArrayList<ChessStep>(size * size);
        //默认黑方先下
        nextStepUser = 1;
    }

    /**
     * 添加一步棋
     * @param x
     * @param y
     * @param userId
     * @return
     */
    public ChessStep addStep(int x,int y,String userId){
        if(over){
            return null;
        }
        if(!getColorUser(nextStepUser).equals(userId)){
            //只有轮到该用户下棋时才落子
            return null;
        }
        // 前端坐标系与数组不同 转换一次
        int realx = y;
        int realy = x;
        int tempValue = getUserColor(userId);
        if(chess[realx][realy]  == 0 ){
            chess[realx][realy] = tempValue;
            ChessStep step = new ChessStep();
            step.setUserId(userId);
            step.setX(x);
            step.setY(y);
            step.setValue(tempValue);
            steps.add(step);
            if(getWinner(realx,realy)!=null){
                this.setOver(true);
                step.setSucces(true);
                System.out.println(step);
                return step;
            }
            changeNextStepUser();
            return step;
        }else{
            return null;
        }
    }

    /**
     * 获取用户棋子颜色
     * @param userId
     * @return
     */
    public int getUserColor(String userId){
        if(black.equals(userId)){
            return 1;
        }else if(white.equals(userId)){
            return 2;
        }
        return 0;
    }
    /**
     * 根据棋子颜色获取用户
     * @param color
     * @return
     */
    public String getColorUser(long color){
        if(color == 2){
            return white;
        }else if(color == 1){
            return black;
        }
        return null;
    }

    /**
     * 传入一个用户id,返回游戏中另一个用户的id
     * @param userId
     * @return
     */
    public String getAnotherUser(String userId){
        if(white.equals(userId)){
            return black;
        }else{
            return white;
        }
    }

    private void changeNextStepUser(){
        if(nextStepUser == 2){
            this.nextStepUser = 1;
        }else if(nextStepUser == 1){
            this.nextStepUser = 2;
        }
    }

    /**
     * 查看是否决出胜负,
     * @return
     */
    public String getWinner(int i,int j){
        int xMax = chess.length-1;
        int yMax = chess[0].length-1;
        System.out.println("check["+i+"]["+j+"]");
        //查看横向
        //检查竖向
        //检查竖直向下 和竖直向上 的与当前点相同颜色的点数量
        if((checkWin(chess,i,j,-1,0) + checkWin(chess,i,j,1,0)) >= 4){
            String winner = getColorUser(chess[i][j]);
            System.out.println("用户:"+winner+"胜利");
            return winner;
        }
        //检查水平向右 和水平向左 的与当前点相同颜色的点数量
        if((checkWin(chess,i,j,0,-1) + checkWin(chess,i,j,0,1)) >= 4){
            String winner = getColorUser(chess[i][j]);
            System.out.println("用户:"+winner+"胜利");
            return winner;
        }
        //检查斜向右上 斜向左下 的与当前点相同颜色的点数量
        if((checkWin(chess,i,j,-1,1) + checkWin(chess,i,j,1,-1)) >= 4){
            String winner = getColorUser(chess[i][j]);
            System.out.println("用户:"+winner+"胜利");
            return winner;
        }
        //检查斜向左上 斜向右下 的与当前点相同颜色的点数量
        if((checkWin(chess,i,j,-1,-1) + checkWin(chess,i,j,1,1)) >= 4){
            String winner = getColorUser(chess[i][j]);
            System.out.println("用户:"+winner+"胜利");
            return winner;
        }
        return null;
    }

    /**
     *
     * @param chess
     * @param i
     * @param j
     * @param iRange
     * @param jRange
     * @return
     */
    public int checkWin(long[][] chess,int i,int j,int iRange,int jRange){
        int iMax = chess.length-1;
        int jMax = chess[0].length-1;
        long targetvalue = chess[i][j];

        int tempi = i+iRange;
        int tempj = j+jRange;
        if(tempi < 0 || tempi >iMax  || tempj < 0 || tempj>jMax){
            return 0;
        }
        long temp = chess[tempi][tempj];
        int num = 0;
        while( temp == targetvalue && tempi >= 0 && tempi <=iMax  && tempj >= 0 && tempj <=jMax){
            temp = chess[tempi][tempj];
            if(temp == targetvalue){
                num ++;
            }
            tempi = tempi+iRange;
            tempj = tempj+jRange;
        }
        System.out.println("target:"+targetvalue+",iRange:"+iRange+",jRange:"+jRange+",num:"+num);
        return num;
    }

    public static void main(String[] args) {
        SerializerManager.setDefault(SerializerAlgorithm.JSON);
        String black = "1";
        String white = "2";
        Game game = new Game(black,white,15);

        game.printChess(game.getChess());
        if(!game.isOver()){
            game.addStep(0,10,"1");
        }
        System.out.println("--------------------------");
        if(!game.isOver()) {
            game.addStep(0, 11, "1");
        }
        System.out.println("--------------------------");
        if(!game.isOver()) {
            game.addStep(0, 12, "1");
        }
        System.out.println("--------------------------");
        if(!game.isOver()) {
            game.addStep(0, 13, "1");
        }
        System.out.println("--------------------------");
        if(!game.isOver()) {
            game.addStep(2, 1, "2");
        }
        System.out.println("--------------------------");
        if(!game.isOver()) {
            game.addStep(14, 14, "1");
        }
        System.out.println("--------------------------");
        if(!game.isOver()) {
            game.addStep(1, 10, "1");
        }
        System.out.println("--------------------------");
        if(!game.isOver()) {
            game.addStep(2, 10, "2");
        }
        System.out.println("--------------------------");
        game.printChess(game.getChess());
    }

    public void printChess(long[][] chess){
        for(long[] i:chess){
            for(long j:i){
                System.out.print(j+"  ");
            }
            System.out.println();
        }
    }

}
